<template>
  <div class="knowledge-graph-container">
    <!-- 侧边栏 -->
    <div class="sidebar">
      <div class="header flex-shrink-0">
        <div class="title">{{ route.query.name || '知识图谱' }}</div>
      </div>

      <div class="stats-card flex-shrink-0">
        <div class="stats-content">
          <div class="stats-title">知识点总量（条）</div>
          <div class="stats-value">{{ totalCount }}</div>
        </div>
      </div>

      <el-card class="category-card flex-shrink-0">
        <div class="category">
          <div class="category-item" v-for="item in categories" :key="item.level">
            <span class="level-name">{{ item.name }}</span>
            <span class="level-count">{{ item.count }}</span>
          </div>
        </div>
      </el-card>

      <el-card class="learning-content-card flex-shrink-0">
        <div class="content-header">
          <span>关联学习内容</span>
          <span class="count">{{ learningContentCount }}</span>
        </div>
        <div class="content-tags">
          <el-tag class="content-tag" v-for="tag in tags" :key="tag" size="small">
            {{ tag }}
          </el-tag>
        </div>
      </el-card>
    </div>

    <!-- 图谱容器 -->
    <div
      class="graph-container"
      v-loading="loading"
      element-loading-text="加载中..."
      element-loading-background="#fffffff2"
    >
      <div v-show="loading || pageData?.id" id="graph" ref="graphContainer"></div>
      <el-empty class="mt-100px" description="暂无数据" v-if="!loading && !pageData?.id" />
    </div>

    <!-- 节点详情抽屉 -->
    <NodeDetailDrawer
      v-model="drawerVisible"
      :node="currentNode"
      @open-unit="openUnitDialog"
      @open-resource="openResourceDialog"
    />
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, nextTick } from 'vue'
import { useRoute } from 'vue-router'
import { KnowledgeApi } from '@/api/school/knowledge/knowledge'
import { G6Config } from './G6config'
import NodeDetailDrawer from './NodeDetailDrawer.vue'
const totalCount = ref(0)
const learningContentCount = ref(0)
// const graphContainer = ref(null)
const drawerVisible = ref(false)
const currentNode = ref(null)
const pageData = ref({})
const loading = ref(true) // 添加loading状态

const route = useRoute()
const knowledgeId = ref(Number(route.query.knowledgeId) || 1) // 从路由query中获取knowledgeId，默认值为1

const { graphContainer } = G6Config({
  async init() {
    // 生成并设置数据
    // 获取知识图谱节点树
    try {
      const data = await KnowledgeApi.getKnowledgeNodeTree(knowledgeId.value)
      if (!data) {
        loading.value = false
        return
      }
      pageData.value = data
      initPageData(data)
      return data
    } catch (error) {
      loading.value = false
    }
  },
  onNodeClick(model) {
    currentNode.value = model
    drawerVisible.value = true
  },
  onRendered() {
    // 图谱渲染完成后隐藏loading
    loading.value = false
  }
})
// 分类数据 - 移除"发展阶段"，只保留"核心能力"和"具体表现"
const categories = ref([
  { level: 1, name: '核心能力', count: 0 },
  { level: 2, name: '具体表现', count: 0 }
])

// 学习内容标签
const tags = ref([])

// 统计节点数量和分类
function countNodesByType(data) {
  // 使用数组存储各层级的节点数量，索引对应层级深度
  const counts = []

  // 递归统计节点数量和类型
  function traverse(node, depth = 0) {
    // 确保数组在对应索引位置有值
    if (counts.length <= depth) {
      counts.length = depth + 1
      counts.fill(0, counts.length - 1)
    }

    // 增加对应层级的计数
    counts[depth]++

    // 递归子节点并增加深度
    if (node?.children?.length) {
      node.children.forEach((child) => traverse(child, depth + 1))
    }
  }

  traverse(data, 0)

  return counts
}

// 统计学习资源
function countLearningResources(data) {
  const allTags = new Set()
  let resourceCount = 0

  // 递归遍历节点
  function traverse(node) {
    // 累加学习资源数量
    if (node?.resourceCount) {
      resourceCount += node.resourceCount
    }

    // 收集标签
    if (node?.tags) {
      node.tags.forEach((tag) => allTags.add(tag))
    }

    // 递归子节点
    if (node?.children?.length) {
      node.children.forEach((child) => traverse(child))
    }
  }

  traverse(data)

  // 统计总数
  learningContentCount.value = resourceCount

  // 转换为数组
  return Array.from(allTags)
}
const initPageData = (data) => {
  // 统计节点
  const counts = countNodesByType(data)

  // 更新分类数据 - 只保留"核心能力"和"具体表现"
  // 核心能力使用counts[1]（一级子节点）
  // 具体表现使用counts索引大于1的之和（二级及以下节点）
  const specificPerformanceCount = counts.reduce((sum, count, index) => {
    if (index > 1) {
      return sum + count
    }
    return sum
  }, 0)

  categories.value = [
    { level: 1, name: '核心能力', count: counts[1] || 0 },
    { level: 2, name: '具体表现', count: specificPerformanceCount }
  ]

  // 更新标签数据
  tags.value = countLearningResources(data)

  // 更新知识点总量（除根节点外的所有节点）
  const total = counts.reduce((sum, count, index) => {
    if (index > 0) {
      return sum + count
    }
    return sum
  }, 0)
  totalCount.value = total
}

</script>

<style lang="scss" scoped>
.knowledge-graph-container {
  display: flex;
  overflow: hidden;
}

.sidebar {
  z-index: 10;
  display: flex;
  width: 300px;
  height: $content-height;
  padding: 20px;
  overflow-y: auto;
  background-color: #fff;
  border-right: 1px solid #f0f0f0;
  box-shadow: 0 4px 16px rgb(0 0 0 / 8%);
  flex-direction: column;
  gap: 24px;
}

.header {
  margin-bottom: 20px;
}

.title {
  position: relative;
  padding-left: 16px;
  font-size: 20px;
  font-weight: 700;
  color: #1d3557;
}

.title::before {
  position: absolute;
  top: 4px;
  bottom: 4px;
  left: 0;
  width: 6px;
  background: linear-gradient(to bottom, var(--el-color-primary), var(--el-color-primary));
  border-radius: 3px;
  content: '';
}

.stats-card {
  position: relative;
  padding: 20px;
  overflow: hidden;
  background: linear-gradient(120deg, #edf7ff 0%, #f7fbff 100%);
  border-left: 6px solid var(--el-color-primary);
  border-radius: 16px;
  box-shadow: 0 4px 12px rgb(30 136 229 / 15%);
}

.stats-card::before {
  position: absolute;
  top: -20px;
  right: -20px;
  width: 80px;
  height: 80px;
  background: var(--el-color-primary);
  border-radius: 50%;
  content: '';
  opacity: 0.1;
}

.stats-content {
  position: relative;
  z-index: 1;
  text-align: center;
}

.stats-title {
  margin-bottom: 10px;
  font-size: 14px;
  font-weight: 600;
  color: #457b9d;
}

.stats-value {
  font-size: 32px;
  font-weight: 800;
  letter-spacing: 1px;
  color: #1d3557;
  text-shadow: 0 2px 4px rgb(0 0 0 / 5%);
}

.category-card {
  background: linear-gradient(135deg, #fff 0%, #fbfdff 100%);
  border: none;
  border-radius: 16px;
  box-shadow: 0 4px 12px rgb(0 0 0 / 4%);
}

:deep(.el-card__body) {
  padding: 0 !important;
}

.category-item {
  display: flex;
  justify-content: space-between;
  padding: 16px 20px;
  font-size: 14px;
  color: #5a7f9c;
  border-bottom: 1px solid #f0f5ff;
  transition: all 0.3s ease;
}

.category-item:hover {
  background-color: #f7fbff;
  transform: translateX(5px);
}

.category-item:last-child {
  border-bottom: none;
}

.level-name {
  font-weight: 600;
  color: #1d3557;
}

.level-count {
  font-size: 18px;
  font-weight: 800;
  color: var(--el-color-primary);
}

.learning-content-card {
  background: linear-gradient(135deg, #fff 0%, #fbfdff 100%);
  border: none;
  border-radius: 16px;
  box-shadow: 0 4px 12px rgb(0 0 0 / 4%);
}

.content-header {
  display: flex;
  padding: 20px 20px 16px;
  font-size: 16px;
  font-weight: 700;
  color: #1d3557;
  border-bottom: 1px solid #f0f5ff;
  justify-content: space-between;
}

.count {
  font-weight: 800;
  color: var(--el-color-primary);
}

.content-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  padding: 20px;
}

.content-tag {
  padding: 6px 16px;
  font-size: 13px;
  color: var(--el-color-primary);
  background: linear-gradient(145deg, #e3f2fd, var(--el-color-primary-light-9));
  border: none;
  border-radius: 18px;
  box-shadow: 0 2px 6px rgb(33 150 243 / 15%);
  transition: all 0.3s ease;
}

.content-tag:hover {
  transform: translateY(-3px);
  box-shadow: 0 4px 10px rgb(33 150 243 / 25%);
}

.graph-container {
  position: relative;
  height: $content-height;
  overflow: hidden;
  background: linear-gradient(135deg, #edf7ff 0%, #e3f2fd 100%);
  flex: 1;
}

#graph {
  position: relative;
  width: 100%;
  height: 100%;
  background-color: rgb(255 255 255 / 90%);
  box-shadow:
    0 10px 30px rgb(0 0 0 / 6%),
    inset 0 0 0 1px rgb(255 255 255 / 90%);
  backdrop-filter: blur(3px);
  user-select: none;

  :deep(.g6-minimap) {
    position: absolute !important;
    bottom: 0;
    background-color: #f0f8ff70;
    border: 2px solid #e2e2e2;
    box-sizing: content-box;
  }
}
</style>
